#include <gl.h>
#include <device.h>

#include "fdecl.h"
#include "misc.h"

#define ZOOM 19
#define TRANSLATION_RATE 0.01e0

Matrix Identity = {{1.0, 0.0, 0.0, 0.0},
		   {0.0, 1.0, 0.0, 0.0},
		   {0.0, 0.0, 1.0, 0.0},
		   {0.0, 0.0, 0.0, 1.0}};

Angle incl, azim;
double dist;
Coord X_Translation, Y_Translation, Z_Translation;

int active_parameter;

long main_menu, superquadric_menu;


void set_projection()
{
  long x, y;

  getsize(&x, &y);
  perspective(ZOOM, (double)x / y, 5.0, 2000.0);
}


void user_reset()
{
  incl = 900;
  azim = 0;
  dist = 100.0;
  X_Translation = -1.7;
  Y_Translation = 0;
  Z_Translation = 0;
}


void quit()
{
  exit(0);
}


void modify_superquadric_parameters (int item)
{
  active_parameter = item;
}


void user_init() 
{
  qdevice(ESCKEY);
  qdevice(LEFTMOUSE);
  qdevice(MIDDLEMOUSE);
  qdevice(RIGHTMOUSE);
  user_reset();

  superquadric_menu = defpup("Superquadric Parameters %t %F|sc %x1|a1 %x2|a2 %x3|a3 %x4|e1 %5|e2 %6|tapx %7|tapy %8|bend1 %9|bend2 %10|bend3 %11",
			     modify_superquadric_parameters);

  main_menu = defpup("Main Menu %t|Superquadric Menu %m|Reset Viewpoint %f|Quit %f", 
		     superquadric_menu, user_reset, quit);

}    


extern hybroid *h1;

void user()
{
  short	dev, val;
  static int dist_adj, pos_adj, x, y, xold, yold;
  double near, far ;

  if (qtest()) {
    dev = qread(&val);
    switch (dev) {

    case ESCKEY:
      quit();
      break;
	    
    case LEFTMOUSE:
      xold = getvaluator(MOUSEX);
      yold = getvaluator(MOUSEY);
      dist_adj = val;
      break;
		
    case MIDDLEMOUSE:
      xold = getvaluator(MOUSEX);
      yold = getvaluator(MOUSEY);
      pos_adj = val;
      active_parameter = 0;
      break;

    case RIGHTMOUSE:
      dopup(main_menu);
      break;
		
    case REDRAW:
      reshapeviewport();
      set_projection();
      break;
    }
  }

  if ((active_parameter > 0) && dist_adj) {
    x = getvaluator(MOUSEX);
    y = getvaluator(MOUSEY);

    switch (active_parameter) {
    case 1: 
      h1->sc += 0.01 * (y - yold);
      h1->sc = Max(h1->sc, 0.0);
      break;

    case 2: 
      h1->a1 += 0.01 * (y - yold);
      h1->a1 = Limit(h1->a1, 0.0, 1.0);
      break;

    case 3: 
      h1->a2 += 0.01 * (y - yold);
      h1->a2 = Limit(h1->a2, 0.0, 1.0);
      break;

    case 4: 
      h1->a3 += 0.01 * (y - yold);
      h1->a3 = Limit(h1->a3, 0.0, 1.0);
      break;

    case 5: 
      h1->e1 += 0.01 * (y - yold);
      h1->e1 = Limit(h1->e1, 0.0, 3.0);
      break;

    case 6: 
      h1->e2 += 0.01 * (y - yold);
      h1->e2 = Limit(h1->e2, 0.0, 3.0);
      break;

    case 7: 
      h1->tapx += 0.01 * (y - yold);
      h1->tapx = Limit(h1->tapx, -2.0, 2.0);
      break;

    case 8: 
      h1->tapy += 0.01 * (y - yold);
      h1->tapy = Limit(h1->tapy, -2.0, 2.0);
      break;

    case 9: 
      h1->bend1 += 0.01 * (y - yold);
      h1->bend1 = Limit(h1->bend1, -4.0, 4.0);
      break;

    case 10: 
      h1->bend2 += 0.01 * (y - yold);
      h1->bend2 = Limit(h1->bend2, -1.0, 1.0);
      break;

    case 11: 
      h1->bend3 += 0.01 * (y - yold);
      h1->bend3 = Limit(h1->bend3, 0.1, 1.0);
      break;
 
    }
/*
    compute_superquadric(h1);
*/
    compute_superquadric_taper_bend(h1);

    xold = x;
    yold = y;
  }
  else if (dist_adj) {
    x = getvaluator(MOUSEX);
    y = getvaluator(MOUSEY);

    if (getbutton(XKEY)==0 && getbutton(YKEY)==0 && getbutton(ZKEY)==0)
      {
	dist += x + y - xold - yold;
	dist = Max(dist, 10.0);
      }
    else if (getbutton(XKEY)==1 && getbutton(ZKEY)==1) {
      X_Translation += TRANSLATION_RATE * (x - xold);
      Z_Translation += TRANSLATION_RATE * (y - yold);
    }
    else if (getbutton(XKEY)==1 && getbutton(YKEY)==1) {
      X_Translation += TRANSLATION_RATE * (x - xold);
      Y_Translation += TRANSLATION_RATE * (y - yold);
    }
    else if (getbutton(YKEY)==1 && getbutton(ZKEY)==1) {
      Y_Translation += TRANSLATION_RATE * (x - xold);
      Z_Translation += TRANSLATION_RATE * (y - yold);
    }
    else {
      if (getbutton(XKEY)==1) X_Translation += TRANSLATION_RATE * (x - xold);
      if (getbutton(YKEY)==1) Y_Translation += TRANSLATION_RATE * (y - yold);
      if (getbutton(ZKEY)==1) Z_Translation += TRANSLATION_RATE * (y - yold);
    }

    xold = x;
    yold = y;
  }
  else if (pos_adj) {
    x = getvaluator(MOUSEX);
    y = getvaluator(MOUSEY);
    azim -= x - xold;
    incl += y - yold;
    xold = x;
    yold = y;
  }

  loadmatrix   (Identity);
  polarview    (dist, azim, incl, 0);
  translate(X_Translation, Y_Translation, Z_Translation);
}



void toggle(String s, int b, int f)
{
  char  buff[30];

  sprintf(buff, "Turn %s %s %%f", s, b ? "off" : "on");
  addtopup(main_menu, buff, f);
}


